#region imported Namespaces
using System;
using System.Data;
using System.Collections.Specialized;
using System.Data.SqlClient;

using BO = PHSRAG.Insight21.BusinessObjects;
using Utility = PHSRAG.Utility;
using ICachePolicy = PHSRAG.Insight21.Policy.ICachePolicy;
using AccessRightBit = PHSRAG.Security.Enumerations.AccessRightBit;
#endregion

namespace PHSRAG.Insight21.Purchasing
{
	#region UserOrderLineItem Class
	/// <summary>
	/// Business class for User Order Line Item. It encapsulates the data and behaviour 
	/// to view , add , edit and delete a line item which the user has access to.
	/// </summary>
	public class UserOrderLineItem
	{
		#region Constants
		private const int DefaultId							= 0;		
		private const decimal DefaultAmount					= 0;
				
//		//Stored Procedure Parameter Name
		private const string FundNumberParamName			= "@fundNumber";
		private const string AccountNumberParamName			= "@accountNumber";
//
//		//Stored Procedure Name
		private const string GetFundIdSPName				= "GetFundId";
		private const string GetAccountIdSPName				= "GetAccountId";
		#endregion
		
		#region Instance Variables
		private DataRow lineItemRow;
		#endregion

		#region Enumeration
		// Enumerates the parameters for the
		// stored procedures used for validation
		// of fund number and account number
		private enum ValidateParametersIndex
		{
			Id,
			Number
		}
		#endregion

		#region Instance Properties
		/// <summary>
		/// Gets and sets the LineID. Returns Default Id if value in datatable is DBNull.Value
		/// </summary>
		public int LineID
		{
			get
			{
				object lineID = lineItemRow[Constants.LineIDColumnName];
				return (lineID == DBNull.Value) ? DefaultId : (int)lineID;
			}				
			//get
			//{
			//    //---------------------------------------------------------------------------------
			//    //02/21/2008 - Fix for TrackIt 7829 - Cast Error - occurred when object is null
			//    //---------------------------------------------------------------------------------
			//    int ret = 0;
			//    object lineID = lineItemRow[Constants.LineIDColumnName];
			//    if (lineID is int)
			//        ret = (int)lineID;
			//    else
			//        ret = DefaultId;
			//    return ret;
			//}
			set{lineItemRow[Constants.LineIDColumnName] = value;}
		}

		/// <summary>
		/// Gets and sets the OrderID. Returns Default Id if value in datatable is DBNull.Value
		/// </summary>
		public int OrderID
		{
			get
			{
				object orderID = lineItemRow[Constants.OrderIDColumnName];
				return (orderID == DBNull.Value) ? DefaultId : (int)orderID;
			}				
			//get
			//{
			//    //---------------------------------------------------------------------------------
			//    //02/21/2008 - Fix for TrackIt 7829 - Cast Error - occurred when object is null
			//    //---------------------------------------------------------------------------------
			//    int ret = 0;
			//    object orderID = lineItemRow[Constants.OrderIDColumnName];
			//    if (orderID is int)
			//        ret = (int)orderID;
			//    else
			//        ret = DefaultId;
			//    return ret;
			//}
            set { lineItemRow[Constants.OrderIDColumnName] = value; }
		}

		/// <summary>
		/// Gets and sets the FundId. Returns Default Id if value in datatable is DBNull.Value
		/// </summary>
		public int FundId
		{
			get
			{
				object fundID = lineItemRow[Constants.FundIDColumnName];
				return (int)lineItemRow[Constants.FundIDColumnName];
			}
			//get
			//{
			//    //---------------------------------------------------------------------------------
			//    //02/21/2008 - Fix for TrackIt 7829 - Cast Error - occurred when object is null
			//    //---------------------------------------------------------------------------------
			//    int ret = 0;
			//    object fundID = lineItemRow[Constants.FundIDColumnName];
			//    if (fundID is int)
			//        ret = (int)fundID;
			//    else
			//        ret = DefaultId;
			//    return ret;
			//}
            set { lineItemRow[Constants.FundIDColumnName] = value; }
		}

		/// <summary>
		/// Gets and sets the FundNumber. Returns empty string if value in datatable is DBNull.Value
		/// </summary>
		public string FundNumber
		{
			get
			{
				object fundNumber = lineItemRow[Constants.FundNumberColumnName];
				return (fundNumber == DBNull.Value) ? string.Empty : fundNumber.ToString();
			}
			//get
			//{
			//    //---------------------------------------------------------------------------------
			//    //02/21/2008 - Fix for TrackIt 7829 - Cast Error - occurred when object is null
			//    //---------------------------------------------------------------------------------
			//    string ret = "";
			//    object fundNumber = lineItemRow[Constants.FundNumberColumnName];
			//    if (fundNumber is string)
			//        ret = fundNumber.ToString();
			//    else
			//        ret = string.Empty;
			//    return ret;
			//}

            set { lineItemRow[Constants.FundNumberColumnName] = value; }
		}

		/// <summary>
		/// Gets and sets the AccountId. Returns Default Id if value in datatable is DBNull.Value
		/// </summary>
		public int AccountId
		{
			get
			{
				object accountID = lineItemRow[Constants.AccountIDColumnName];
				return (accountID == DBNull.Value) ? DefaultId : (int)accountID;
			}
			//get
			//{
			//    //---------------------------------------------------------------------------------
			//    //02/21/2008 - Fix for TrackIt 7829 - Cast Error - occurred when object is null
			//    //---------------------------------------------------------------------------------
			//    int ret = 0;
			//    object accountID = lineItemRow[Constants.AccountIDColumnName];
			//    if (accountID is int)
			//        ret = (int)accountID;
			//    else
			//        ret = DefaultId;
			//    return ret;
			//}
            set { lineItemRow[Constants.AccountIDColumnName] = value; }
		}

		/// <summary>
		/// Gets and sets the AccountNumber. Returns empty string if value in datatable is DBNull.Value
		/// </summary>
		public string AccountNumber
		{
			get
			{
				object accountNumber = lineItemRow[Constants.AccountNumberColumnName];
				return (accountNumber == DBNull.Value) ? string.Empty : accountNumber.ToString();
			}
			//get
			//{
			//    //---------------------------------------------------------------------------------
			//    //02/21/2008 - Fix for TrackIt 7829 - Cast Error - occurred when object is null
			//    //---------------------------------------------------------------------------------
			//    string ret = "";
			//    object accountNumber = lineItemRow[Constants.AccountNumberColumnName];
			//    if (accountNumber is string)
			//        ret = accountNumber.ToString();
			//    else
			//        ret = string.Empty;
			//    return ret;
			//}

            set { lineItemRow[Constants.AccountNumberColumnName] = value; }
		}
		/// <summary>
		/// Gets and sets the Amount. Returns default amount if value in datatable is DBNull.Value
		/// </summary>
		public decimal Amount
		{
			get
			{
				object amount = lineItemRow[Constants.AmountColumnName];
				return (amount == DBNull.Value) ? DefaultAmount : Convert.ToDecimal(amount);
			}
			//get
			//{
			//    //---------------------------------------------------------------------------------
			//    //02/21/2008 - Fix for TrackIt 7829 - Cast Error - occurred when object is null
			//    //---------------------------------------------------------------------------------
			//    decimal ret = 0;
			//    object amount = lineItemRow[Constants.AmountColumnName];
			//    if (amount is int)
			//        ret = Convert.ToDecimal(amount);
			//    else
			//        ret = DefaultAmount;
			//    return ret;
			//}

            set{lineItemRow[Constants.AmountColumnName] = value;}
		}

		/// <summary>
		/// Gets and sets the Comment. Returns empty string if value in datatable is DBNull.Value
		/// </summary>
		public string Comment
		{
			get
			{
				object comment = lineItemRow[Constants.CommentColumnName];
				return (comment == DBNull.Value) ? string.Empty : comment.ToString();
			}
			//get
			//{
			//    //---------------------------------------------------------------------------------
			//    //02/21/2008 - Fix for TrackIt 7829 - Cast Error - occurred when object is null
			//    //---------------------------------------------------------------------------------
			//    string ret = "";
			//    object comment = lineItemRow[Constants.CommentColumnName];
			//    if (comment is string)
			//        ret = comment.ToString();
			//    else
			//        ret = string.Empty;
			//    return ret;
			//}
			
            set{lineItemRow[Constants.CommentColumnName] = value;}
		}
		/// <summary>
		/// Gets and sets the RequestorName. Returns empty string if value in datatable is DBNull.Value
		/// </summary>
		public string RequestorName
		{
			get
			{
				object requestorName = lineItemRow[Constants.RequestorColumnName];
				return (requestorName == DBNull.Value) ? string.Empty : requestorName.ToString();
			}

			//get
			//{
			//    //---------------------------------------------------------------------------------
			//    //02/21/2008 - Fix for TrackIt 7829 - Cast Error - occurred when object is null
			//    //---------------------------------------------------------------------------------
			//    string ret = "";
			//    object requestorName = lineItemRow[Constants.RequestorColumnName];
			//    if (requestorName is string)
			//        ret = requestorName.ToString();
			//    else
			//        ret = string.Empty;
			//    return ret;
			//}

            set { lineItemRow[Constants.RequestorColumnName] = value; }
		}

		/// <summary>
		/// Gets the RowState of the row of this line item.
		/// </summary>
		public DataRowState CurrentState
		{
			get{return lineItemRow.RowState;}
		}
		#endregion
		
		#region Constructor
		/// <summary>
		/// Intializes the base class with specified cache policy,
		/// and this class with supplied datarow.
		/// </summary>
		/// <param name="dataRow">Contains the data for the line item</param>
		/// <param name="cachePolicy">Specified cache policy for line item</param>
		public UserOrderLineItem(DataRow dataRow)
		{
			lineItemRow = dataRow;
		}
		#endregion

		#region Private Methods
		/// <summary>
		/// Validates fund and account number. If fund number or account number is not
		/// provided it raises an exception informing the user to provide the same. If
		/// fund number and account number are provided they are validated against the
		/// exisitng fund and account in the database.
		/// </summary>
		/// <param name="connection">open connection to database</param>
		public void ValidateFundAndAccount(SqlConnection connection)
		{
			if(AccountNumber.Equals(string.Empty))
				throw new Exception(@"Please provide the account number.");
			else
				ValidateAccountNumber(connection);

			if(FundNumber.Equals(string.Empty))
				throw new Exception(@"Please provide the fund number.");
			else
				ValidateFundNumber(connection);
		}
	
		/// <summary>
		/// Validates the fund number against the existing values in the database.
		/// It gets the fund id by providing the fund number. If the fund id returned
		/// is null, its considered invalid and an exception is raised 
		/// informing the user about it.
		/// </summary>
		/// <param name="connection">open connection to database</param>
		private void ValidateFundNumber(SqlConnection connection)
		{
			object fundIDReturned = 
				Utility.DataAccess.ExecuteScalar(connection, GetFundIdSPName, 
				Utility.DataAccess.BuildSqlParameterArray(FundNumberParamName, 
				SqlDbType.VarChar, FundNumber));
			
			if(fundIDReturned == null)
				throw new Exception(String.Format(@"The specified Fund Number '{0}' is invalid.", FundNumber));
			else
				FundId = (int)fundIDReturned;
		}

		/// <summary>
		/// Validates the account number against the existing values in the database.
		/// It gets the account id by providing the account number. If the account id
		/// returned is null, its considered invalid and an exception is
		/// raised informing the user about it.
		/// </summary>
		/// <param name="connection">open connection to database</param>
		private void ValidateAccountNumber(SqlConnection connection)
		{
			object accountIDReturned = 
				Utility.DataAccess.ExecuteScalar(connection, GetAccountIdSPName, 
				Utility.DataAccess.BuildSqlParameterArray(AccountNumberParamName, 
				SqlDbType.VarChar, AccountNumber));
			
			if(accountIDReturned == null)
				throw new Exception(String.Format(@"The specified Account Number '{0}' is invalid.", AccountNumber));
			else
				AccountId = (int)accountIDReturned;			
		}
		#endregion
	}
	#endregion
}
